# load("//main:compile_rule.bzl","compile")
# load("//main:link_rule.bzl","link")
# load("//main:zip_archive_rule.bzl","zip_archive")

def _src_compile_impl(ctx):
    outputs = []

    # g++ srouce1 source2 -o xxx.o -c
    for src in ctx.files.srcs:  # src: File
        out = ctx.actions.declare_file("{}.o".format(src.path[:-4]))
        print(">>> Compling {} -> {}".format(src, out))
        
        inputs = [src]
        inputs.extend(ctx.files.hdrs)

        args = ctx.actions.args()
        args.add(src)
        args.add("-o")
        args.add(out)
        args.add("-c")

        ctx.actions.run(
            executable = "/usr/bin/g++",
            arguments  = [args],
            inputs     = inputs,
            outputs    = [out],
        )
        outputs.append(out)

    return [DefaultInfo(files = depset(outputs))]


compile = rule (
    implementation = _src_compile_impl,
    attrs = {
        "srcs" : attr.label_list(
            allow_files = True,
            doc = "input source files",
        ),
        "hdrs" : attr.label_list(
            allow_files = True,
            doc = "input header files",
        ),
    },
    executable = False,
    test       = False,
)

def _link_impl(ctx):
    exec_file = ctx.outputs.exec_file

    args = ctx.actions.args()
    args.add_all(ctx.files.libs)

    args.add("-o")
    args.add(exec_file)
    args.add("-B")
    args.add("/usr/bin")

    ctx.actions.run(
        executable = "/usr/bin/g++",
        arguments  = [args],
        inputs     = ctx.files.libs,
        outputs    = [exec_file],
    )

    return [DefaultInfo(files = depset([exec_file]))]


link = rule (
    implementation = _link_impl,
    attrs = {
        "libs" : attr.label_list(
            allow_files = True,
            doc = "input obj files",
        ),
        "exec_file" : attr.output(),      # 最后的可执行文件
    },
    executable = False,
    test       = False,
)

def _impl_zip_rchive(ctx):
    archive_file = ctx.outputs.archive_file

    args = ctx.actions.args()
    args.add(archive_file)
    args.add_all(ctx.files.files)

    ctx.actions.run(
        executable = "zip",
        arguments  = [args],
        inputs     = ctx.files.files,
        outputs    = [archive_file]
    )

    return DefaultInfo(
        files = depset([archive_file]),
    )

zip_archive = rule(
    implementation = _impl_zip_rchive,
    attrs = {
        "files" : attr.label_list(allow_files=True),  # 要打包哪些文件
        "archive_file" : attr.output(mandatory=True), # 输出的压缩包名
    },
)

def application(name, srcs, hdrs, output):
    compile_target = "{}-complie".format(name)
    link_target    = "{}-link".format(name)
    output_target  = "{}".format(name)
    compile (
        name = compile_target,
        srcs = srcs,
        hdrs = hdrs,
    )

    link (
        name      = link_target,
        libs      = [compile_target],   # src_compile Target对应的输出
        exec_file = "yangxianpku",      # 这个名字不能与main这个文件夹的名字重复
    ) 

    zip_archive (
        name         = name,            # 这里是最终的输出
        files        = [link_target, 'README.md'],
        archive_file = output,
    )
